#include "JSValueWrapper.h"

namespace AwesomiumDotNet
{
	class MyWebViewListener : public Awesomium::WebViewListener
	{
	public:
		typedef void (*w_onBeginNavigation) (const std::string& url, const std::wstring& frameName);
		typedef void (*w_onBeginLoading) (const std::string& url, const std::wstring& frameName, int statusCode, const std::wstring& mimeType);
		typedef void (*w_onFinishLoading) ();
		typedef void (*w_onCallback) (const std::string& name, const Awesomium::JSArguments& args);
		typedef void (*w_onReceiveTitle) (const std::wstring& title, const std::wstring& frameName);
		typedef void (*w_onChangeTooltip) (const std::wstring& tooltip);
		typedef void (*w_onChangeCursor) (const HCURSOR& cursor);
		typedef void (*w_onChangeKeyboardFocus) (bool isFocused);
		typedef void (*w_onChangeTargetURL) (const std::string& url);

		w_onBeginNavigation s_onBeginNavigation;
		w_onBeginLoading s_onBeginLoading;
		w_onFinishLoading s_onFinishLoading;
		w_onCallback s_onCallback;
		w_onReceiveTitle s_onReceiveTitle;
		w_onChangeTooltip s_onChangeTooltip;
		w_onChangeCursor s_onChangeCursor;
		w_onChangeKeyboardFocus s_onChangeKeyboardFocus;
		w_onChangeTargetURL s_onChangeTargetURL;

		void set_onBeginNavigation(w_onBeginNavigation ptr2F) {
			s_onBeginNavigation = ptr2F; }
		void set_onBeginLoading(w_onBeginLoading ptr2F) {
			s_onBeginLoading = ptr2F; }
		void set_onFinishLoading(w_onFinishLoading ptr2F) {
			s_onFinishLoading = ptr2F; }
		void set_onCallback(w_onCallback ptr2F) {
			s_onCallback = ptr2F; }
		void set_onReceiveTitle(w_onReceiveTitle ptr2F) {
			s_onReceiveTitle = ptr2F; }
		void set_onChangeTooltip(w_onChangeTooltip ptr2F) {
			s_onChangeTooltip = ptr2F; }
		void set_onChangeCursor(w_onChangeCursor ptr2F) {
			s_onChangeCursor = ptr2F; }
		void set_onChangeKeyboardFocus(w_onChangeKeyboardFocus ptr2F) {
			s_onChangeKeyboardFocus = ptr2F; }
		void set_onChangeTargetURL(w_onChangeTargetURL ptr2F) {
			s_onChangeTargetURL = ptr2F; }


	public:
		MyWebViewListener()
		{
		}

		void onBeginNavigation(const std::string& url, const std::wstring& frameName)
		{
			s_onBeginNavigation(url, frameName);
		}

		void onBeginLoading(const std::string& url, const std::wstring& frameName, int statusCode, const std::wstring& mimeType)
		{
			s_onBeginLoading(url, frameName, statusCode, mimeType);
		}

		void onFinishLoading()
		{
			s_onFinishLoading();
		}

		void onCallback(const std::string& name, const Awesomium::JSArguments& args)
		{
			s_onCallback(name, args);
		}

		void onReceiveTitle(const std::wstring& title, const std::wstring& frameName)
		{
			s_onReceiveTitle(title, frameName);
		}
		void onChangeTooltip(const std::wstring& tooltip)
		{
			s_onChangeTooltip(tooltip);
		}

	#if defined(_WIN32)
		void onChangeCursor(const HCURSOR& cursor)
		{
			s_onChangeCursor(cursor);
		}
	#endif

		void onChangeKeyboardFocus(bool isFocused)
		{
			s_onChangeKeyboardFocus(isFocused);
		}

		void onChangeTargetURL(const std::string& url)
		{
			s_onChangeTargetURL(url);
		}
	};

	namespace Args
	{
	public ref class BeginNavigationEventArgs : System::EventArgs
	{
	public:
		property String^ Url;
		property String^ FrameName;
	public:
		BeginNavigationEventArgs(String^ url, String^ frameName) {
			this->Url = url;
			this->FrameName = frameName;
		}
	};

	public ref class BeginLoadingEventArgs : System::EventArgs
	{
	public:
		property String^ Url;
		property String^ FrameName;
		property int StatusCode;
		property String^ MimeType;
	public:
		BeginLoadingEventArgs(String^ url, String^ frameName, int statusCode, String^ mimeType) {
			this->Url = url;
			this->FrameName = frameName;
			this->StatusCode = statusCode;
			this->MimeType = mimeType;
		}
	};

	public ref class FinishLoadingEventArgs : System::EventArgs
	{
	};

	public ref class CallbackEventArgs : System::EventArgs
	{
	public:
		property String^ Name;
		const List<JSValue^>^ args;
	public:
		CallbackEventArgs(String^ name, const List<JSValue^>^ args) {
			this->Name = name;
			this->args = args;
		}
	};

	public ref class ReceiveTitleEventArgs : System::EventArgs
	{
	public:
		property String^ Title;
		property String^ FrameName;
	public:
		ReceiveTitleEventArgs(String^ title, String^ frameName) {
			this->Title = title;
			this->FrameName = frameName;
		}
	};

	public ref class ChangeTooltipEventArgs : System::EventArgs
	{
	public:
		property String^ Tooltip;
	public:
		ChangeTooltipEventArgs(String^ tooltip) {
			this->Tooltip = tooltip;
		}
	};

	public ref class ChangeCursorEventArgs : System::EventArgs
	{
	public:
		// Cursor cursor;
	public:
		ChangeCursorEventArgs() {
			// this->cursor = cursor;
		}
	};

	public ref class ChangeKeyboardFocusEventArgs : System::EventArgs
	{
	public:
		property bool IsFocused;
	public:
		ChangeKeyboardFocusEventArgs(bool isFocused) {
			this->IsFocused = isFocused;
		}
	};

	public ref class ChangeTargetUrlEventArgs : System::EventArgs
	{
	public:
		property String^ Url;
	public:
		ChangeTargetUrlEventArgs(String^ url) {
			this->Url = url;
		}
	};

	}
}
